#ifndef _T2DECODER_H
#define _T2DECODER_H

#ifdef WIN32
#include "./avi/mpeg4_decore_interface.h"
#else
#include <types.h>
#include <sys_config.h>
#include <retcode.h>
#include <api/libc/string.h>
#include <api/libc/printf.h>
#include <osal/osal.h>
#include <hld/snd/snd_dev.h>
#include <hld/snd/snd.h>
#include <api/libmp/lib_mp.h>

#define MAX_FRAME_BUF_NO    6
#define MAX_OTHER_BUF_NO    10

#endif

#define DATA_BLOCK_MAX_NUM 150

#define INVALID_TIME 0xffffffff
#define INVALID_STREAM_ID 0xffff

#ifndef SEEK_SET
#define SEEK_SET    0
#endif
#ifndef SEEK_CUR
#define SEEK_CUR    1
#endif
#ifndef SEEK_END
#define SEEK_END    2
#endif

#define AUDIO_WAITRETRY					0
#define AUDIO_SUCCESS					1
#define AUDIO_NOTSUPPORTED				2

//normal: normal play mode
//skip_b: only skip b frame in FF mode
//skip_b_p: skip both b and p in FF mode
//step: step or pause mode
//stop: stop mode
#define VIDEO_PLAY_MODE_NORMAL			0
#define VIDEO_PLAY_MODE_SKIP_B			1
#define VIDEO_PLAY_MODE_SKIP_B_P		2
#define VIDEO_PLAY_MODE_STEP			3
#define VIDEO_PLAY_MODE_STOP         	4
#define VIDEO_FLUSH_BUFFER              5
#define VIDEO_PLAY_MODE_RESUME_STOP     6

//none: no any operation to audio which means audio keeps previous state
//on: decoder audio on
//off: decoder audio off
#define AUDIO_PLAY_MODE_NONE		    0
#define AUDIO_PLAY_MODE_ON				1
#define AUDIO_PLAY_MODE_OFF				2

#define CODEC_FILE_TELL_POS             (BYTE *)(0xfffffffe)
#define CODEC_FILE_SEEK                 (BYTE *)(0xffffffff)

#define FRAME_PICTURE 1
#define FIELD_PICTURE 2

#define FORWARD_PLAY            1
#define BACKWARD_PLAY           2

#define ADDR_NO_ALIGN           0
#define ADDR_4_BYTE_ALIGN       1
#define ADDR_16_BYTE_ALIGN      2
#define ADDR_64_BYTE_ALIGN      3
#define ADDR_256_BYTE_ALIGN     4
#define ADDR_1K_BYTE_ALIGN      5
#define ADDR_4K_BYTE_ALIGN      6
#define ADDR_16K_BYTE_ALIGN     7
#define ADDR_64K_BYTE_ALIGN     8
#define ADDR_256K_BYTE_ALIGN    9
#define ADDR_1M_BYTE_ALIGN      10
#define ADDR_2M_BYTE_ALIGN      11
#define ADDR_4M_BYTE_ALIGN      12

#define INTERLACE_SCAN      0
#define PROGRESSIVE_SCAN    1

#define DERR_OK                      0
#define DERR_UNSUPPORTED_VIDEO_CODEC 1
#define DERR_UNSUPPORTED_AUDIO_CODEC 2
#define DERR_MP4_NOT_RECT_SHAPE		 3
#define DERR_MP4_SHAPE_GRAY			 4
#define DERR_MP4_INTERLACE_MC		 5
#define DERR_MP4_GMC				 6
#define DERR_MP4_SPRITE_STATIC		 7
#define DERR_MP4_N_BIT				 8
#define DERR_MP4_QPEL_MC			 9
#define DERR_MP4_COMPLEXITY_EST		 10
#define DERR_MP4_RVLC				 11
#define DERR_MP4_NEW_PRED			 12
#define DERR_MP4_REDUCED_RESOLUTION	 13
#define DERR_MP4_PARTITIONED_FRAME	 14
#define DERR_MP4_SPRITE				 15
#define DERR_MP4_ERROR_BITSTREAM     16
#define DERR_MP4_ERROR_OBMC	         17
#define DERR_MP4_NO_INDEX            18
#define DERR_MP4_TOO_BIG_INTERLEAVE  19
#define DERR_UNSUPPORTED_RESOLUTION  20
#define DERR_MAX                     21
#define DERR_MP4_DRM_AUTH            22
#define DERR_UNSUPPORTED_FRAME_RATE  23
#define DERR_UNKNOWN                 0xff   
/*
typedef struct
{
	
        BYTE VideoPlaymode; //Nomal, skip_b, skip_b_p
        BYTE AudioPlaymode; //mute, no_mute
        BYTE StreamType; 
        BYTE PlayDir; //Play direction(forward or backward)
        int ScrRatio; //0: normal speed: 1: 2X slow 2: 4X slow play 3: 8X slow play 4: 16X slow play 5: 32X slow play
        WORD video_stream_id; //video stream ID to be decoded
        WORD audio_stream_id; //audiostream ID to be decoded
        WORD subp_stream_id; //SP stream ID to be decoded
        WORD  prog_id;
        WORD  subt_lang_id;

        DWORD SearchTime;
        BOOL  subt_onoff;
        BOOL renew; //this indictates that any field of "t2DecoderControl" is changed
}t2DecoderControl;*/

typedef struct
{
	BOOL renew; //this indictates that any field of "t2DecoderControl" is changed
	BYTE VideoPlaymode; //Nomal, skip_b, skip_b_p
	BYTE AudioPlaymode; //mute, no_mute
	int ScrRatio; //0: normal speed: 1: 2X slow 2: 4X slow play 3: 8X slow play 4: 16X slow play 5: 32X slow play
	WORD video_stream_id; //video stream ID to be decoded
	WORD audio_stream_id; //audiostream ID to be decoded
	WORD subp_stream_id; //SP stream ID to be decoded
	BYTE StreamType; 
    BYTE PlayDir; //Play direction(forward or backward)
    DWORD SearchTime;

	BOOL  subt_onoff;
	WORD  prog_id;
	WORD  subt_lang_id;

}t2DecoderControl;



typedef struct
{
	DWORD pack_start_id; 
	DWORD pack_end_id;
	DWORD SecSize; //The sector size
	BOOL PlayEnd; //indicates that play last sectors
	DWORD max_pack_num; 
}t2DecoderBuffer;

typedef struct
{
	int sx;
	int sy;
	int ey;
	int colcon;
}CHG_CC_COMMAND;
/*
colcon:
bit 0-3: Background pixel color code
    	bit 4-7: Pattern pixel color code
    	bit 8-11: Emphasis pixel-1 color code
    	bit 12-15: Emphasis pixel-2 color code.
bit 16-19: Background pixel contrast
    	bit 20-23: Pattern pixel contrast
    	bit 24-27: Emphasis pixel-1 contrast
    	bit 28-31: Emphasis pixel-2 contrast
*/

typedef struct
{
    DWORD FBStride;
    DWORD FBMaxHeight;
/*    BYTE *y;
    BYTE *cb;
    BYTE *cr;*/
    BYTE *FrmBuf;  //used only for SW_DECODE
    BYTE *DispBuf; //In HW_DISPLAY mode, first 4 bytes store frame buffer addr, last 4 byte stor dv buffer addr
}t2FrameBuffer;

typedef struct
{
    BYTE *Buf;
    DWORD size;
}t2DecOtherBuf;

typedef struct
{
    DWORD FBStride;
    DWORD FBMaxHeight;
    DWORD FBNo;
    DWORD FBAlign;
    DWORD OtherBufNo;
    DWORD OtherBufSize[MAX_OTHER_BUF_NO]; 
    DWORD OtherBufAlign[MAX_OTHER_BUF_NO]; 
}t2DecoderCap;

typedef struct 
{
    UINT32 fb_y[MAX_FRAME_BUF_NO];
    UINT32 fb_c[MAX_FRAME_BUF_NO];
    UINT32 dv_y[MAX_FRAME_BUF_NO];
    UINT32 dv_c[MAX_FRAME_BUF_NO];
    UINT32 fb_max_stride;
    UINT32 fb_max_height;
    UINT32 dv_max_stride;
    UINT32 dv_max_height;
    INT32 fb_num;
    UINT32 neighbor_mem;
    UINT32 colocate_mem;
    UINT32 cmdq_base;
    UINT32 cmdq_len;
    UINT32 vbv_start;
    UINT32 vbv_len;
}HWMemConfig;

typedef struct 
{
#ifndef WIN32
    enum SndDupChannel AudioChannel;
#endif
    t2FrameBuffer *FrameBuffer;
    t2DecOtherBuf *OtherBuffer;
    HWMemConfig HWMem;
    BOOL preview;
    BOOL file_type;  //add by mark;
    DWORD (*DecoderReadData)(BYTE *buf, DWORD size);
    BOOL (*DecoderSeekData)(INT64 offset, DWORD origin);
    INT64 (*DecoderTellPos)(void);
    BOOL (*GetCtrlCmd)(t2DecoderControl *DecoderCtrl);
    void(*mp_callback_func)(unsigned long type, unsigned long param);
}DEC_INIT_PAR, *PDEC_INIT_PAR;

#if 0
typedef struct
{
    DWORD BufSize[MAX_AVHWBUF_NO]; 
    DWORD BufAlign[MAX_AVHWBUF_NO]; 
}t2AVHWCap;
#endif

typedef struct
{
    DWORD DecTag;
    DWORD AudioDecSource;
}t2AudioDecID;

typedef struct _DEC_CHAPTER_INFO
{
    DWORD nb_chapter;           /* number of chapters */
    INT32 cur_chapter;          /* current chapter */
    INT32 cur_start_time;       /* current chapter start time in second */
    INT32 cur_end_time;         /* current chapter end time in second */
    char  cur_title[10];        /* current chapter title name */
    INT32 dst_chapter;          /* current chapter */
    INT32 dst_start_time;       /* current chapter start time in second */
    INT32 dst_end_time;         /* current chapter end time in second */

    UINT32 reserved;            /* reserved */
}DEC_CHAPTER_INFO, *PDEC_CHAPTER_INFO;

typedef struct _DEC_STREAM_INFO
{
    char VideoDec[10]; //the name of the video codec. For now, we support below video codec:
                       //"mp43", "XVID", "unknown"
    char AudioDec[10]; //the name of the audio codec. For now, we support below audio codec:
                       //"PCM", "MP3", "AC3", "DTS", "unknown"
    DWORD AudioStreamNum; //The audio track number in the media stream
    DWORD SubStreamNum; //The subtitle stream number in the media stream
    DWORD TotalFrameNum; //The total frame number of the media stream
    DWORD FramePeriod; //The frame period of the media stream
    DWORD TotalTime; //Total play time of the media stream
    int   width; //The width of the media stream. The maximum width the video decoder can support is 720.
    int   height; //The height of the media stream. The maximum height the video decoder can support is 576.
    DWORD VideoBitrate;
    DWORD AudioBitrate;
    DWORD AudioChannelNum;
    UINT32 fsize;
    INT32 AudioSampleRate;
    INT32 video_codec_tag;
    INT32 cur_audio_stream_id;
    INT32 cur_sub_stream_id;
	
	INT32 cur_prog_id;
	DWORD ProgNum;
//	char  ProgName[32][255];
    char AudioName[20][10];
    char SubName[20][10];   //the name of the subtitle codec. 
    char AudioLanguage[20][10]; //the name of the audio language
    char SubLanguage[20][10]; //the name of the subtitle language
	
}DEC_STREAM_INFO, *PDEC_STREAM_INFO;

typedef enum
{
    TT_CUT = 0,
    TT_FADE_IN_OUT = 1,
    TT_DISSOLVE = 2,
    TT_WIPE_FROM_TOP = 3,
    TT_WIPE_FROM_BOTTOM = 4,
    TT_WIPE_FROM_LEFT = 5,
    TT_WIPE_FROM_RIGHT = 6,
    TT_WIPE_DIAGONAL_LEFT = 7,
    TT_WIPE_DIAGONAL_RIGHT = 8
}TransType;

typedef struct
{
    DWORD FileOffset;
    DWORD Time;
	WORD audio_stream_id; //audiostream ID to be decoded
	WORD subp_stream_id; //SP stream ID to be decoded
}DEC_PLAYPOINT_INFO, *PDEC_PLAYPOINT_INFO;

typedef struct
{
    BYTE *pOutputBuf;
    DWORD OutputX;
    DWORD Outputy;
    DWORD OutputWidth;
    DWORD OutputHeight;
}DEC_OUTPUT_WIN, *PDEC_OUTPUT_WIN;

/****************************************************
These functions declared below used by decoder
****************************************************/

/*----------------------------------------------------
Name: 
    OutputFrame
Description: 
    Output the decoded frame from decoder. In T6301/3/5,
    the decoded frame will be sent to display engine immidiately.
    In T6307, the decoded frame cound be sent to encoder as well.
    For now, this function only supports T6301/3/5. And any 
    postprocess should be done through this function.
Parameters: 
    IN:
	y_buf: Y buffer address
    	cb_buf: Cb buffer address
    	cr_buf: Cr buffer address
    	width: the width of the decoded frame
    	height: the height of the decoded frame
    	Stride: Y buffer stride, cb/cr buffer stride
    	is the half of the Y buffer stride
    OUT:
Return: 
------------------------------------------------------*/
void OutputFrame(unsigned char *disp_buf,
			  UINT32 width,
			  UINT32 height, 
			  unsigned char pic_type,
              unsigned char prediction_type);
			  
/*----------------------------------------------------
Name: 
    t2GetCurrentField
Description: 
    Get current display field.
Parameters: 
    IN:
    OUT:
Return: 
	Return current field. 
	0: even field 1: odd field
------------------------------------------------------*/
unsigned char t2GetCurrentField(void);

/*----------------------------------------------------
Name: 
    t2GetCurrentTVMode
Description: 
    Get current TV mode
Parameters: 
    IN:
    OUT:
Return: 
    0: PAL, 1: NTSC
------------------------------------------------------*/
unsigned char t2GetCurrentTVMode(void);

/*----------------------------------------------------
Name: 
    t2SetVSyncCallback
Description: 
    Set vsync callback function, because there is bug in 
    T6303, therefore a 10 ms timer interrupt is used here 
    to emulate VSync. VSync callback function is called 30
    times/second(NTSC) or 25(PAL). If decoder set vsync 
    callback function, it shall call "t2ResetVSyncCallback" to
    release the vsync callback function
Parameters: 
    IN:
    OUT:
Return: 
------------------------------------------------------*/
void t2SetVSyncCallback(void  * cb);

/*----------------------------------------------------
Name: 
    t2ResetVSyncCallback
Description: 
    Release vsync callback function, If decoder set vsync 
    callback function, it shall call "t2ResetVSyncCallback" to
    release the vsync callback function
Parameters: 
    IN:
    OUT:
Return: 
------------------------------------------------------*/
void t2ResetVSyncCallback(void);

/*******SP related functions******/
/*----------------------------------------------------
Name: 
	t2SetSPColorCode
Description: 
	Set SP color code
Parameters: 
    IN:
    	colorcode:
    	bit 0-3: Background pixel color code
    	bit 4-7: Pattern pixel color code
    	bit 8-11: Emphasis pixel-1 color code
    	bit 12-15: Emphasis pixel-2 color code
    OUT:
Return: 
------------------------------------------------------*/
void t2SetSPColorCode(unsigned short colorcode);

/*----------------------------------------------------
Name: 
	t2SetSPContrast
Description: 
	Set SP contrast
Parameters: 
    IN:
    	contrast:
    	bit 0-3: Background pixel contrast
    	bit 4-7: Pattern pixel contrast
    	bit 8-11: Emphasis pixel-1 contrast
    	bit 12-15: Emphasis pixel-2 contrast
    OUT:
Return: 
------------------------------------------------------*/
void t2SetSPContrast(unsigned short contrast);

/*----------------------------------------------------
Name: 
	t2SetSPArea
Description: 
	Set SP display area
Parameters: 
    IN:
    	sx: start X-coordinate
    	sy: start Y-coordinate
    	ex: end X-coordinate
    	ey: end Y-coordinate
    OUT:
Return: 
------------------------------------------------------*/
void t2SetSPArea(unsigned long sx, unsigned long sy, unsigned long ex, unsigned long ey);

/*----------------------------------------------------
Name: 
	DecoderSPOnOff
Description: 
	Decoder call this function to turn on/off SP.
Parameters: 
    IN:
    	OnOff: TRUE: decoder turn on SP, FALSE: decoder turn off SP
    	ForcedlyDisp: TRUE: forcedly display current SP irrespective 
    	to the ON/OFF display state of the SP, otherwise, FALSE. 
    OUT:
Return: 
------------------------------------------------------*/
void DecoderSPOnOff(BOOL OnOff, BOOL ForcedlyDisp);

/*----------------------------------------------------
Name: 
	t2SetSPChg_ColCon
Description: 
	pass SP_CHG_COLCON information to firmware. If there is no SP_CHG_COLCON 
	information exists in SP bitstream, this function should not be called or 
	set item_number to 0.
Parameters: 
    IN:
    	pCommand: pointer to the first chg_cc_command structure start address
	item_number: the total numbers of chg_cc_command, 
	if there is no SP_CHG_COLCON information in SP bitstream, then item_number = 0.
    OUT:
Return: 
------------------------------------------------------*/
void t2SetSPChg_ColCon(CHG_CC_COMMAND *pCommand, unsigned long item_number);

/*----------------------------------------------------
Name: 
	GetCPUFreq
Description: 
	Get current CPU frequency
Parameters: 
    IN:
    OUT:
Return: 
	Current CPU frequency in HZ
------------------------------------------------------*/
DWORD GetCPUFreq(void);

/*----------------------------------------------------
Name: 
	GetRegC0Count
Description: 
	get CPU couter
Parameters: 
    IN:
    	OnOff: TRUE: decoder turn on SP, FALSE: decoder turn off SP
    OUT:
Return: 
	Current CPU courter
------------------------------------------------------*/
DWORD GetRegC0Count(void);

/*-------------------------------------------------------------------
Name: 
    DecoderSleep
Description: 
    Decoder call this function to sleep which will suspend decoder task 
    immidiately and come back to task after "n" ms
Parameters: 
    [IN]
        n: the time that decoder will be suspended for in ms
    [OUT]
Return: 
-------------------------------------------------------------------*/
void DecoderSleep(int n);

/*----------------------------------------------------
Name: 
    t2AudioSelectSource
Description: 
    Select audio source type.
Parameters: 
    IN:
        id: audio stream id.
        0xC0-0xDF: MPEG1 layer1/2/3 audio stream
        0x80-0x87: AC3 audio stream
        0x88-0x8F: DTS audio stream
        0x90-0x97: SDDS audio stream
        0xA0-0xA7: LPCM audio stream
        0xB0: CDDA(PCM)
        0x70-0x7f: BYE1 stream
        0x60-0x6f: DTSCD stream	special case, select and send PCM stream, but no annlog output

        Note: later, we will merge mp2 and mp3 audio stream
        into mpeg audio stream
    OUT:
Return: 
    TRUE, if success, otherwise, FALSE 
------------------------------------------------------*/
BOOL t2AudioSelectSource(DWORD id,int audio_codec_tag, int audio_channels, 
                int audio_sample_rate, int audio_byte_rate, 
                int audio_block_size, int audio_sample_per_block, int audio_bits_per_sample,
                int audio_encode_opt, unsigned char* extra_data);

/*----------------------------------------------------
Name: 
    t2OutputAudio
Description: 
    Output audio stream.
Parameters: 
    IN:
        buf: the pointer to the audio stream to be output
        size: the audio stream size to be output
    OUT:
Return: 
	AUDIO_WAITRETRY		: Waits for re-send the audio stream,
							this case, the buffer is full
	AUDIO_SUCCESS		: Sent successful
	AUDIO_NOTSUPPORTED	: Audio stream is not supported.
    
------------------------------------------------------*/
int t2OutputAudio(BYTE *buf, DWORD size);

/*----------------------------------------------------
Name: 
    t2StopAudio
Description: 
    Stop audio playback
Parameters: 
    IN:
    OUT:
Return: 
------------------------------------------------------*/
void t2StopAudio(void);

DWORD t2AudioGetTime(void);
void t2AudioSetTime(DWORD rtime);
DWORD t2AudioBufferedRemain(void);
BOOL t2AudioConfig(DWORD fs, WORD bitres, WORD nch);
DWORD mp4_multu64div(UINT32 v1, UINT32 v2, UINT32 v3);

#define C_MPEG4_DECODER_NO      -1
#define C_XD_LICENSE_NO       0
#define C_XD_LICENSE_YES      1
#define C_MPEG4_LICENSE_YES     2

/* return -1: no mpeg4 decoder
   return 0 : has mpeg4 decoder, but not xd certified
   return 1 : has mpeg4 decoder, and pass xd certified */
int check_xd_enable();

/*-------------------------------------------------------------------
Name: 
    t2GetSrcResolution
Description: 
    Decoder call this function to get the original resolution of
    current movie from navigator. Because there are some VCD that 
    have no sequence header. In this case, decoder has to call this
    function to get the resolutoin of the movie.
    Parameters: 
    [IN]
    [OUT]
    p_width: the original width of the source movie
    p_height: the original height of the source movie
Return: 
    This function always return TRUE for now
-------------------------------------------------------------------*/
BOOL t2GetSrcResolution(DWORD *p_width, DWORD *p_height);

/*-------------------------------------------------------------------
Name: 
    t2GetScanMode
Description: 
    Decoder call this function to get current scan mode
Parameters: 
    [IN]
    [OUT]
Return: 
PROGRESSIVE_SCAN: current scan mode is progressive scan
INTERLACE_SCAN: current scan mode is interlace scan
-------------------------------------------------------------------*/
unsigned char t2GetScanMode(void);

/*-------------------------------------------------------------------
Name: 
    t2GetDisplayMode
Description: 
    Decoder call this function to get current display mode
Parameters: 
    [IN]
    [OUT]
Return: 
0: current display mode is pan & scan
1: current display mode is letterbox
3: current display mdoe is normal
-------------------------------------------------------------------*/
int t2GetDisplayMode(void);

/*-------------------------------------------------------------------
Name: 
    DecoderSetDE
Description: 
    Decoder call this function to set display engine. This function
    is only called by mpeg file decoder for now, because NV cant know 
    the TV mode of the mpeg file decoder.
Parameters: 
    [IN]
    Width: the width of the media stream
    Height: the height of the media stream 
    FramePeriod: the frame period of the media stream
    [OUT]
Return: 
-------------------------------------------------------------------*/
void DecoderSetDE(DWORD Width, DWORD Height, DWORD FramePeriod, BYTE AspectRatio, DWORD ParWidth, DWORD ParHeight);

/*---------------------------------------------------------
Name: t2AudioSeekStream
Description:
	Seeks the stream position in a audio stream.
	ONLY support BYE1 audio stream seeking and
	ONLY invoked by bye1 decoder.
Parameters: 
    [IN] 	mode : indicating seek direction
    				0 for backward as 1 for forward
    		ms : gives the time in ms to seek 
    				in the audio stream
    [OUT]
Return:
	The new position in the streamTRUE,
	Or ZERO if seeking Out of BOF/EOF in the stream. (seeking overhead)
---------------------------------------------------------*/
DWORD t2AudioSeekStream(int mode, unsigned int ms);

/*---------------------------------------------------------
Name: t2AudioIsCbr
Description: 
	Inquires if the playing audio stream is CBR/VBR from DSP
Parameters: 
    [IN]	NONE
    [OUT]	NONE
Return: 
	return 	TRUE if CBR,
			FALSE if VBR.
---------------------------------------------------------*/
BOOL t2AudioIsCbr(void);

/*-------------------------------------------------------------------
Name: 
    t2AudioLookForExtDec
Description: 
    Check if there is external audio codec. 
Parameters: 
    [IN]
        tag: Audio tag in AVI header.
    [OUT]
Return: 
    The audio souce ID which will be used to select audio source. 
    0: if cant find matched external audio codec. 
-------------------------------------------------------------------*/
DWORD t2AudioLookForExtDec(DWORD tag);

/*-------------------------------------------------------------------
Name: 
    t2AudioResetNewDec
Description: 
    Disable external audio decoder, this function is called in 
    Mpeg4DecoderReset.
Parameters: 
    [IN]
    [OUT]
Return: 
-------------------------------------------------------------------*/
void t2AudioResetNewDec(void);

#endif  // _T2DECODER_H

